// Copyright (C) 2010  Joan Puigcerver Perez, <joapuipe@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef __SAXREQUESTSHANDLER_HPP__
#define __SAXREQUESTSHANDLER_HPP__

#include <cc++/common.h>

#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/Attributes.hpp>

#include <XMLUtils.hpp>
#include <Genres.hpp>
#include <Media.hpp>
#include <Link.hpp>

#include <string>

#ifdef XERCES_CPP_NAMESPACE_USE
XERCES_CPP_NAMESPACE_USE
#endif

/**
 * \class SAXRequestsHandler
 *
 * This function is used to handle the actions of the XML parser when a request is being parsed.
 * Its behaviour is similar to SAXMoviesHandler and SAXPeopleHandler.
 * 
 * \see SAXMoviesHandler
 * \see SAXPeopleHandler
 */
class SAXRequestsHandler: public DefaultHandler {
public:
  /** The different types of requests. */
  typedef enum { R_DISTANCE, R_DISTANCEN, R_CENTER } RequestType;

private:
  XMLCh * _kattrSource, * _kattrTarget, * _kattrHops;
  
  XercesString buffer;
  enum { F_NONE, F_MIN, F_MAX, F_SUSPENDED, F_MEDIA, F_GENRE, F_WORK } filt_proc;
  
  // Parsed objects...
  RequestType request_type;
  unsigned short int min_year, max_year;
  bool suspended;
  Genres genres;
  Media medias;
  Work works;
  std::string source;
  std::string target;
  unsigned int hops;
  
public:  
  /** Constructor. */
  SAXRequestsHandler();

  /** This function is executed by the parser when the document starts. */
  void startDocument ();

  /** This function is executed by the parser when the document ends. */
  void endDocument ();

  /** 
   * Receive notification of the start of an element.
   *
   * @param uri The URI of the associated namespace for this element
   * @param localname The local part of the element name
   * @param qname The QName of this element
   * @param attrs The specified or defaulted attributes. 
   */
  void startElement ( const XMLCh* const uri,
		      const XMLCh* const localname,
		      const XMLCh* const qname,
		      const Attributes&  attrs );

  /** 
   * Receive notification of the end of an element.
   *
   * @param uri The URI of the associated namespace for this element
   * @param localname The local part of the element name
   * @param qname The QName of this element
   */
  void endElement( const XMLCh* const uri, 
		   const XMLCh* const localname,
		   const XMLCh* const qname );
  
  /** 
   * Receive notification of character data inside an element.
   *
   * @param chars The characters.
   * @param length The number of caracters to use from the character array.
   */
  void characters( const XMLCh* const chars,
		   const XMLSize_t length );

  /**
   * Report a fatal XML parsing error. 
   * 
   * @param exception The error information encoded as an exception.
   */
  void fatalError( const SAXParseException& exception );

  /**
   * Report a XML parsing error, usually it happens when the request does not follow the schema.
   * 
   * @param exception The error information encoded as an exception.
   */  
  void error(const SAXParseException &exception);

  /** Function used to obtain the request type. */
  RequestType getRequestType(void) const { return request_type; }
  /** Function used to obtain the min year field from filtering options. */
  unsigned int getMinYearFilter(void) const { return min_year; }
  /** Function used to obtain the max year field from filtering options. */
  unsigned int getMaxYearFilter(void) const { return max_year; }
  /** Function used to obtain the suspended field from filtering options. */
  bool getSuspendedFilter(void) const { return suspended; }
  /** Function used to obtain the genres field from filtering options. */
  Genres getGenresFilter(void) const { return genres; }
  /** Function used to obtain the medias field from filtering options. */
  Media  getMediasFilter(void) const { return medias; }
  /** Function used to obtain the works field from filtering options. */
  Work getWorksFilter(void) const { return works; }
  /** Function used to obtain the source field from a request. */
  std::string getSource(void) const { return source; }
  /** Function used to obtain the target field from a request. */
  std::string getTarget(void) const { return target; }
  /** Function used to obtain the hops field from a request. */
  unsigned int getHops(void) const  { return hops; }
};

#endif
